package com.xjscrm.console.chat.core.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.uzai.mobile.collect.api.MicaTopics;
import com.uzai.mobile.collect.api.dto.MicaTriggerDto;
import com.uzai.mobile.collect.api.dto.trigger.MicaTriggerConversationTalkMsg;
import com.uzai.mobile.collect.api.enums.MicaTalkMsgType;
import com.uzai.mobile.collect.api.enums.MicaTriggerType;
import com.xjscrm.common.exception.BusinessException;
import com.xjscrm.console.chat.core.ChatBaseMsgHandler;
import com.xjscrm.console.chat.enums.ChatMsgType;
import com.xjscrm.console.chat.enums.ChatTalkRecordSendStatus;
import com.xjscrm.console.chat.enums.ChatTalkRecordSource;
import com.xjscrm.console.chat.frame.recv.RReplyMsg;
import com.xjscrm.console.chat.frame.send.SReplySuccessMsg;
import com.xjscrm.console.chat.frame.send.SResultMsg;
import com.xjscrm.console.entity.ChatTalkRecord;
import com.xjscrm.console.entity.ChatTalkSession;
import com.xjscrm.console.mq.producer.SendMsgProducer;
import com.xjscrm.console.service.customer.chat.ChatTalkRecordService;
import com.xjscrm.console.service.customer.chat.ChatTalkSessionService;
import com.xjscrm.console.service.customer.chat.ChatTalkSessionStaffRelService;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author mingyang.chen create in 2024/3/12 09:41
 */
@Component
@Slf4j
public class ChatReplyMsgHandler extends ChatBaseMsgHandler<RReplyMsg> {

    public static final String cacheKey = "xj_reply_limit_%s";

    @Autowired
    private ChatTalkSessionService chatTalkSessionService;
    @Autowired
    private ChatTalkSessionStaffRelService chatTalkSessionStaffRelService;

    @Autowired
    private ChatTalkRecordService chatTalkRecordService;
    @Autowired
    private SendMsgProducer sendMsgProducer;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;


    @Override
    public SResultMsg doHandle(RReplyMsg content, ChannelHandlerContext ctx) {

        try {

            ChatTalkSession talkSession = chatTalkSessionService.getById(content.getMerId(), content.getTalkSessionId());

            if (Objects.isNull(talkSession)) {
                return SResultMsg.fail(content, "会话信息不存在, 请刷新后重试");
            }
//            String limitKey = String.format(cacheKey, talkSession.getId());
//            if (Boolean.FALSE.equals(redisTemplate.opsForValue().setIfAbsent(limitKey, talkSession.getId(), 1, TimeUnit.SECONDS))) {
//                return SResultMsg.fail(content, "操作频繁, 请稍后重试!");
//            }
            chatTalkSessionStaffRelService.addIfAbsent(content.getMerId(), talkSession, content.getStaffId());

            MicaTriggerConversationTalkMsg micaTriggerConversationTalkMsg = new MicaTriggerConversationTalkMsg();

            MicaTalkMsgType contentType = MicaTalkMsgType.getByValue(content.getContentType());
            switch (contentType) {
                case TEXT:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getTextContent()));
                    break;
                case Picture:
                case Emoji:
                case Video:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getUrlContent()));
                    break;
                case Link:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getLinkContent()));
                    break;
                case File:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getFileContent()));
                    break;
                case NameCard:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getNameCardContent()));
                    break;
                case WeApp:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getMiniprogramContent()));
                    break;
                case ShiPinHao:
                    micaTriggerConversationTalkMsg.setContent(JSON.toJSONString(content.getSphContent()));
                    break;
                default:
                    return SResultMsg.fail(content, "聊天消息类型暂不支持, 敬请期待后续更新!");
            }
            micaTriggerConversationTalkMsg.setContentType(content.getContentType());
            micaTriggerConversationTalkMsg.setWxId(talkSession.getConversationId());

            ChatTalkRecord chatTalkRecord = new ChatTalkRecord();

            int currentTime = (int) (System.currentTimeMillis() / 1000L);
            long taskId = IdUtil.getSnowflakeNextId();

            chatTalkRecord.setId(taskId);

            chatTalkRecord.setMerId(content.getMerId());
            chatTalkRecord.setDeviceUniqueId(talkSession.getDeviceUniqueId());
            chatTalkRecord.setTalkSessionId(talkSession.getId());
            chatTalkRecord.setConversationId(talkSession.getConversationId());
            chatTalkRecord.setContentType(contentType.getCode());
            chatTalkRecord.setSource(ChatTalkRecordSource.reply.getCode());
            chatTalkRecord.setSendTime(currentTime);
            chatTalkRecord.setContent(micaTriggerConversationTalkMsg.getContent());
            chatTalkRecord.setSendStatus(ChatTalkRecordSendStatus.sending.getCode());
            chatTalkRecord.setCreateTime(currentTime);
            chatTalkRecord.setCreateBy(content.getStaffId());

            chatTalkRecordService.add(chatTalkRecord);

            ChatTalkSession update = new ChatTalkSession();
            update.setId(talkSession.getId());
            update.setMerId(talkSession.getMerId());
            update.setLastRecvTime((int) (System.currentTimeMillis() / 1000L));
            update.setLastRecvId(taskId);
            update.setUpdateTime((int) (System.currentTimeMillis() / 1000L));
            chatTalkSessionService.update(update);

            micaTriggerConversationTalkMsg.setMessageId(taskId);
            // 构建trigger对象
            MicaTriggerDto micaTriggerDto = MicaTriggerDto.newInstance(micaTriggerConversationTalkMsg, MicaTriggerType.TRIGGER_CONVERSATION_TALK, item -> {
                item.setReqId(taskId);
                item.setDeviceId(talkSession.getDeviceId());
                item.setDeviceType(talkSession.getDeviceType());
            });
            sendMsgProducer.pushMsg(micaTriggerDto, MicaTopics.WW_TRIGGER_TOPIC);

            //
            if (Objects.equals(talkSession.getType(), 110)) {
                chatTalkSessionService.addChatRecvDelayTask(content.getMerId(), content.getStaffId(), talkSession);
            }
            SReplySuccessMsg replySuccessMsg = new SReplySuccessMsg(chatTalkRecord.getId(), talkSession.getId());
            BeanUtils.copyProperties(content, replySuccessMsg);
            replySuccessMsg.fill(content);
            return replySuccessMsg;
        } catch (Exception e) {
            log.error("会话消息回复失败", e);
            throw new BusinessException("消息回复失败, 请稍后重试");
        }
    }

    @Override
    public boolean checkMsg(RReplyMsg baseMsg) {
        return super.checkMsg(baseMsg) || !ObjectUtils.allNotNull(baseMsg.getStaffId(), baseMsg.getTalkSessionId(), baseMsg.getContentType());
    }

    @Override
    public Class<RReplyMsg> msgClass() {
        return RReplyMsg.class;
    }

    @Override
    public ChatMsgType msgType() {
        return ChatMsgType.r_session_reply;
    }
}
